#pragma once
#include <cstdlib>
#include <cassert>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
// 将进程守护化

void daemonSelf(const char *currentPath = nullptr)
{
    // 1. 让调用进程屏蔽掉异常的信号
    signal(SIGPIPE, SIG_IGN); // 防止客户端关闭，服务端写数据崩溃

    // 2. 会话组组长不能调用setid1,所以需要让自己不成为组长，->孤儿进程
    if (fork() > 0)
        exit(0);
    // 子进程就是孤儿进程
    pid_t n = setsid();
    assert(n != -1);

    // 3. 守护进程是脱离终端的。需要关闭或者重定向自己默认打开的文件（输入输出错误）
    // 不建议关闭，我们需要重定向0，1，2文件描述符。防止cout cin cerr发生错误
    // 我们将所有的数据重定向到 /dev/null中
    int fd = -1;
    do
    {
        fd = open("/dev/null", O_WRONLY);
    } while (fd < 0);
    dup2(fd, 0);
    dup2(fd, 1);
    dup2(fd, 2);
    close(fd);

    // 4. 进程执行路径的更改 使用 ls/proc/进程pid 可以查看这个进程的文件
    // 有一个cwd表明当前路径，可以通过某些接口来更改当前路径
    chdir(currentPath);
}